package com.gitee.wsl.compose.ext.ui

import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.State
import androidx.compose.runtime.produceState
import androidx.compose.runtime.snapshotFlow
import kotlinx.coroutines.flow.distinctUntilChanged

/**
 * Created by Niraj on 17-10-2022.
 */
/**
 * Returns whether the lazy list is currently scrolling up.
 */


@Composable
 fun LazyListState.rememberIsTop(): State<Boolean> {
    return remember {
        derivedStateOf {
            this.firstVisibleItemIndex == 0 && this.firstVisibleItemScrollOffset == 0
        }
    }
}

@Composable
fun LazyListState.isInViewport(key: Any): Boolean {
    val isScrollingForward = isScrollingForward()
    return produceState(
        initialValue = false,
        key1 = key,
        key2 = isScrollingForward,
        key3 = this,
    ) {
        snapshotFlow {
            when {
                isScrollingForward -> layoutInfo.visibleItemsInfo.firstOrNull()
                else -> layoutInfo.visibleItemsInfo.lastOrNull()
            }?.key == key
        }
            .distinctUntilChanged()
            .collect { value = it }
    }.value
}


@Composable
fun LazyListState.isScrollingForward(): Boolean {
    var previousIndex by remember(this) { mutableStateOf(firstVisibleItemIndex) }
    var previousScrollOffset by remember(this) { mutableStateOf(firstVisibleItemScrollOffset) }
    return remember(this) {
        derivedStateOf {
            when {
                !canScrollBackward -> true
                !canScrollForward -> false
                previousIndex != firstVisibleItemIndex -> {
                    previousIndex < firstVisibleItemIndex
                }

                else -> {
                    previousScrollOffset <= firstVisibleItemScrollOffset
                }
            }.also {
                previousIndex = firstVisibleItemIndex
                previousScrollOffset = firstVisibleItemScrollOffset
            }
        }
    }.value
}
